library(shiny)
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ───────────────────────────────────────────────────── tidyverse 1.3.2 ──✔ ggplot2 3.3.6     ✔ purrr   0.3.4
✔ tibble  3.1.8     ✔ dplyr   1.0.9
✔ tidyr   1.2.0     ✔ stringr 1.4.0
✔ readr   2.1.2     ✔ forcats 0.5.1── Conflicts ──────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
obps_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-GMKN-2007-10-08-09_obps.csv")
Rows: 394482 Columns: 12── Column specification ──────────────────────────────────────────────────────────────────────
Delimiter: ","
chr  (2): SECCODE, BUYSELL
dbl  (9): NO, TIME, ORDERNO, ACTION, PRICE, VOLUME, TRADENO, TRADEPRICE, OBPLOTNO
date (1): DATE
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# obps_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-2007-10-08_obps.csv")
# obps_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/s1_s2_2007_obps.csv")
obps_df <- obps_df %>% 
  mutate(TIME_S = TIME/1000)
obps_df
order_atts_cumsums_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-GMKN-2007-10-08-09_order_atts_cumsums.csv")
Rows: 394482 Columns: 32── Column specification ──────────────────────────────────────────────────────────────────────
Delimiter: ","
chr   (2): ATT, SECCODE
dbl  (28): VAL, NO, OBPLOTNO, SHAREBAL, BPROFIT, SPROFIT, OBPMINTPRICE, OBPMAXTPRICE, CBOV...
dttm  (1): DATETIMEMLLS
date  (1): DATE
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# order_atts_cumsums_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-2007-10-08_order_atts_cumsums.csv")
# order_atts_cumsums_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/s1_s2_2007_order_atts_cumsums.csv")
order_atts_cumsums_df
obp_cum_atts_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-GMKN-2007-10-08-09_obp_cum_atts.csv")
Rows: 75021 Columns: 6── Column specification ──────────────────────────────────────────────────────────────────────
Delimiter: ","
chr  (3): SECCODE, BUYSELLOBP, TRADESNOTRADES
dbl  (2): OBPLOTNO, TRADEVOL
date (1): DATE
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# obp_cum_atts_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-2007-10-08_obp_cum_atts.csv")
# obp_cum_atts_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/s1_s2_2007_obp_cum_atts.csv")
obp_cum_atts_df
order_atts_cumsums_enhanced_df <- left_join(order_atts_cumsums_df, 
                                         obps_df %>% select(-OBPLOTNO, -SECCODE), 
                                         by = c("NO", "DATE")) %>% 
  select(NO, SECCODE, DATETIMEMLLS, PRICE, TRADEPRICE, VOLUME, 
         DATE, TIME_S, OBPLOTNO, ATT, VAL, 
         SHAREBAL, BPROFIT, SPROFIT, OBPMINTPRICE, OBPMAXTPRICE,
         CBOVOLtdcs, CSOVOLtdcs, BOVOLtdcs, SOVOLtdcs, BTVOLtdcs, STVOLtdcs, 
         CBOVOLobpcs, CSOVOLobpcs, BOVOLobpcs, SOVOLobpcs, BTVOLobpcs, STVOLobpcs,
         sobp, bobp, max_sobp_bobp, minus_max_sobp_bobp, stday, btday, max_std_btd,
         minus_max_std_btd)
order_atts_cumsums_enhanced_df
obp_minmax_tradeprice <- function(att, tradeprice, minmax) {
  at_df <- tibble(att = att,
                  tradeprice = tradeprice)
  if (length(at_df %>%
            filter(att == "BTVOL" | att == "STVOL") %>%
            .$tradeprice)) {
    if (minmax == "min") {
      min(at_df %>%
            filter(att == "BTVOL" | att == "STVOL") %>%
            .$tradeprice %>%
            cummin())
    } else if (minmax == "max") {
      max(at_df %>%
            filter(att == "BTVOL" | att == "STVOL") %>%
            .$tradeprice %>%
            cummax())
    } else quit()
  } else {
      NA
  }
}
obp_minmax_atts_df <- order_atts_cumsums_enhanced_df %>% 
  select(NO, SECCODE, DATE, OBPLOTNO, ATT,
         DATETIMEMLLS, PRICE, TRADEPRICE) %>% 
  group_by(SECCODE, DATE, OBPLOTNO) %>% 
  summarise(OBPBEGIN = min(DATETIMEMLLS), OBPEND = max(DATETIMEMLLS), 
            OBPBEGINNO = min(NO), OBPENDNO = max(NO),
            OBPMINPRICE = min(PRICE), OBPMAXPRICE = max(PRICE))
`summarise()` has grouped output by 'SECCODE', 'DATE'. You can override using the `.groups` argument.
obp_minmax_atts_df
obp_cum_minmax_atts_df <- left_join(obp_cum_atts_df, 
                                    obp_minmax_atts_df %>% select(SECCODE,
                                                                  DATE,
                                                                  OBPLOTNO,
                                                                  OBPBEGIN,
                                                                  OBPBEGINNO,
                                                                  OBPENDNO,
                                                                  OBPEND,
                                                                  OBPMINPRICE,
                                                                  OBPMAXPRICE),
                                    by = c("SECCODE", "DATE", "OBPLOTNO")) %>% 
  select(SECCODE, DATE, OBPLOTNO, TRADEVOL, BUYSELLOBP,
         OBPBEGIN, OBPEND, OBPBEGINNO, OBPENDNO, OBPMINPRICE, OBPMAXPRICE,
         TRADESNOTRADES) #, BUYSELLYIELD, OBPTDVOLRATIO, MINMAXRATIO)
obp_cum_minmax_atts_df
obp_cum_atts_enh_df <- inner_join(obp_cum_minmax_atts_df,
                                  order_atts_cumsums_enhanced_df %>% select(SECCODE,
                                                                            DATE,
                                                                            OBPLOTNO,
                                                                            BPROFIT,
                                                                            SPROFIT),
                                  by = c("SECCODE", "DATE", "OBPLOTNO")) %>% 
  select(SECCODE, DATE, OBPLOTNO, TRADEVOL, BUYSELLOBP,
         BPROFIT, SPROFIT,
         OBPBEGIN, OBPEND, OBPBEGINNO, OBPENDNO, OBPMINPRICE, OBPMAXPRICE,
         TRADESNOTRADES) %>% #, BUYSELLYIELD, OBPTDVOLRATIO, MINMAXRATIO) %>% 
  rename("seccode" = "SECCODE",
         "ddate" = "DATE",
         "obplotno" = "OBPLOTNO",
         "tradevol" = "TRADEVOL",
         "buysellobp" = "BUYSELLOBP",
         "bprofit" = "BPROFIT",
         "sprofit" = "SPROFIT",
         "obpbegin" = "OBPBEGIN",
         "obpend" = "OBPEND",
         "obpbeginno" = "OBPBEGINNO",
         "obpendno" = "OBPENDNO",
         "obpminprice" = "OBPMINPRICE",
         "obpmaxprice" = "OBPMAXPRICE",
         "bprofit" = "BPROFIT",
         "sprofit" = "SPROFIT",
         "tradesnotrades" = "TRADESNOTRADES") %>% 
  distinct()
         # "buysellyield" = "BUYSELLYIELD",
         # "obptdvolratio" = "OBPTDVOLRATIO",
         # "minmaxratio" = "MINMAXRATIO")
obp_cum_atts_enh_df
td_vol_sum_df <- obp_cum_atts_enh_df %>% 
  group_by(seccode, ddate) %>% 
  summarise(tdvolsum = sum(tradevol))
`summarise()` has grouped output by 'seccode'. You can override using the `.groups` argument.
obp_cum_atts_enh_volarranged_df <- left_join(obp_cum_atts_enh_df,
          td_vol_sum_df,
          by = c("seccode", "ddate")) %>% 
  mutate(obpshareintd = tradevol / tdvolsum) %>% 
  select(-tdvolsum) %>% 
  arrange(seccode, ddate, desc(obpshareintd))

obp_cum_atts_enh_volarranged_df
options(digits.secs = 3)
obp_cum_atts_enh_volarranged_df %>%
  write_csv("../order-book-plot-find/cum_errors/resources/for_web_app/obp_cum_atts_enh_df.csv",
            na = "")
order_atts_cumsums_enh2_df <- order_atts_cumsums_enhanced_df %>% 
  mutate(pcolor = if_else(ATT == "BOVOL", 
                          "aquamarine", 
                          if_else(ATT == "SOVOL",
                                  "coral",
                                  "#004481")),
         pshape = 4L,
         psize = 0.5)
order_atts_cumsums_enh2_df
order_atts_cumsums_enh4_df <- order_atts_cumsums_enh2_df %>% 
  arrange(SECCODE, DATE, NO) %>% 
  rename("nno" = "NO",
         "seccode" = "SECCODE",
         "datetimemlls" = "DATETIMEMLLS",
         "price" = "PRICE",
         "tradeprice" = "TRADEPRICE",
         "volume" = "VOLUME",
         "ddate" = "DATE",
         "ttime_s" = "TIME_S",
         "obplotno" = "OBPLOTNO",
         "att" = "ATT",
         "val" = "VAL",
         "sharebal" = "SHAREBAL") %>% 
  select(-BPROFIT, -SPROFIT, -OBPMINTPRICE, -OBPMAXTPRICE)
# options(digits.secs = 3)
order_atts_cumsums_enh4_df %>%
  write_csv("../order-book-plot-find/cum_errors/resources/for_web_app/order_atts_cumsums_enh4_df.csv",
            na = "")
order_atts_cumsums_enh4_df
order_atts_cumsums_enh4_df %>% 
  filter(obplotno == 48851, att == "STVOL") %>% 
  select(nno, price, att, tradeprice, sobp, bobp)
LS0tDQp0aXRsZTogInByZXBhcmVfYmFsX3Rlc3RpbmdfZGZzIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQpgYGB7cn0NCmxpYnJhcnkoc2hpbnkpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KYGBge3J9DQpvYnBzX2RmIDwtIHJlYWRfY3N2KCIuLi9vcmRlci1ib29rLXBsb3QtZmluZC9jdW1fZXJyb3JzL3Jlc291cmNlcy9mb3Jfd2ViX2FwcC9MS09ILUdNS04tMjAwNy0xMC0wOC0wOV9vYnBzLmNzdiIpDQojIG9icHNfZGYgPC0gcmVhZF9jc3YoIi4uL29yZGVyLWJvb2stcGxvdC1maW5kL2N1bV9lcnJvcnMvcmVzb3VyY2VzL2Zvcl93ZWJfYXBwL0xLT0gtMjAwNy0xMC0wOF9vYnBzLmNzdiIpDQojIG9icHNfZGYgPC0gcmVhZF9jc3YoIi4uL29yZGVyLWJvb2stcGxvdC1maW5kL2N1bV9lcnJvcnMvcmVzb3VyY2VzL2Zvcl93ZWJfYXBwL3MxX3MyXzIwMDdfb2Jwcy5jc3YiKQ0Kb2Jwc19kZiA8LSBvYnBzX2RmICU+JSANCiAgbXV0YXRlKFRJTUVfUyA9IFRJTUUvMTAwMCkNCm9icHNfZGYNCmBgYA0KDQoNCmBgYHtyfQ0Kb3JkZXJfYXR0c19jdW1zdW1zX2RmIDwtIHJlYWRfY3N2KCIuLi9vcmRlci1ib29rLXBsb3QtZmluZC9jdW1fZXJyb3JzL3Jlc291cmNlcy9mb3Jfd2ViX2FwcC9MS09ILUdNS04tMjAwNy0xMC0wOC0wOV9vcmRlcl9hdHRzX2N1bXN1bXMuY3N2IikNCiMgb3JkZXJfYXR0c19jdW1zdW1zX2RmIDwtIHJlYWRfY3N2KCIuLi9vcmRlci1ib29rLXBsb3QtZmluZC9jdW1fZXJyb3JzL3Jlc291cmNlcy9mb3Jfd2ViX2FwcC9MS09ILTIwMDctMTAtMDhfb3JkZXJfYXR0c19jdW1zdW1zLmNzdiIpDQojIG9yZGVyX2F0dHNfY3Vtc3Vtc19kZiA8LSByZWFkX2NzdigiLi4vb3JkZXItYm9vay1wbG90LWZpbmQvY3VtX2Vycm9ycy9yZXNvdXJjZXMvZm9yX3dlYl9hcHAvczFfczJfMjAwN19vcmRlcl9hdHRzX2N1bXN1bXMuY3N2IikNCm9yZGVyX2F0dHNfY3Vtc3Vtc19kZg0KYGBgDQoNCmBgYHtyfQ0Kb2JwX2N1bV9hdHRzX2RmIDwtIHJlYWRfY3N2KCIuLi9vcmRlci1ib29rLXBsb3QtZmluZC9jdW1fZXJyb3JzL3Jlc291cmNlcy9mb3Jfd2ViX2FwcC9MS09ILUdNS04tMjAwNy0xMC0wOC0wOV9vYnBfY3VtX2F0dHMuY3N2IikNCiMgb2JwX2N1bV9hdHRzX2RmIDwtIHJlYWRfY3N2KCIuLi9vcmRlci1ib29rLXBsb3QtZmluZC9jdW1fZXJyb3JzL3Jlc291cmNlcy9mb3Jfd2ViX2FwcC9MS09ILTIwMDctMTAtMDhfb2JwX2N1bV9hdHRzLmNzdiIpDQojIG9icF9jdW1fYXR0c19kZiA8LSByZWFkX2NzdigiLi4vb3JkZXItYm9vay1wbG90LWZpbmQvY3VtX2Vycm9ycy9yZXNvdXJjZXMvZm9yX3dlYl9hcHAvczFfczJfMjAwN19vYnBfY3VtX2F0dHMuY3N2IikNCm9icF9jdW1fYXR0c19kZg0KYGBgDQoNCmBgYHtyfQ0Kb3JkZXJfYXR0c19jdW1zdW1zX2VuaGFuY2VkX2RmIDwtIGxlZnRfam9pbihvcmRlcl9hdHRzX2N1bXN1bXNfZGYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnBzX2RmICU+JSBzZWxlY3QoLU9CUExPVE5PLCAtU0VDQ09ERSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IGMoIk5PIiwgIkRBVEUiKSkgJT4lIA0KICBzZWxlY3QoTk8sIFNFQ0NPREUsIERBVEVUSU1FTUxMUywgUFJJQ0UsIFRSQURFUFJJQ0UsIFZPTFVNRSwgDQogICAgICAgICBEQVRFLCBUSU1FX1MsIE9CUExPVE5PLCBBVFQsIFZBTCwgDQogICAgICAgICBTSEFSRUJBTCwgQlBST0ZJVCwgU1BST0ZJVCwgT0JQTUlOVFBSSUNFLCBPQlBNQVhUUFJJQ0UsDQogICAgICAgICBDQk9WT0x0ZGNzLCBDU09WT0x0ZGNzLCBCT1ZPTHRkY3MsIFNPVk9MdGRjcywgQlRWT0x0ZGNzLCBTVFZPTHRkY3MsIA0KICAgICAgICAgQ0JPVk9Mb2JwY3MsIENTT1ZPTG9icGNzLCBCT1ZPTG9icGNzLCBTT1ZPTG9icGNzLCBCVFZPTG9icGNzLCBTVFZPTG9icGNzLA0KICAgICAgICAgc29icCwgYm9icCwgbWF4X3NvYnBfYm9icCwgbWludXNfbWF4X3NvYnBfYm9icCwgc3RkYXksIGJ0ZGF5LCBtYXhfc3RkX2J0ZCwNCiAgICAgICAgIG1pbnVzX21heF9zdGRfYnRkKQ0Kb3JkZXJfYXR0c19jdW1zdW1zX2VuaGFuY2VkX2RmDQpgYGANCg0KYGBge3J9DQpvYnBfbWlubWF4X3RyYWRlcHJpY2UgPC0gZnVuY3Rpb24oYXR0LCB0cmFkZXByaWNlLCBtaW5tYXgpIHsNCiAgYXRfZGYgPC0gdGliYmxlKGF0dCA9IGF0dCwNCiAgICAgICAgICAgICAgICAgIHRyYWRlcHJpY2UgPSB0cmFkZXByaWNlKQ0KICBpZiAobGVuZ3RoKGF0X2RmICU+JQ0KICAgICAgICAgICAgZmlsdGVyKGF0dCA9PSAiQlRWT0wiIHwgYXR0ID09ICJTVFZPTCIpICU+JQ0KICAgICAgICAgICAgLiR0cmFkZXByaWNlKSkgew0KICAgIGlmIChtaW5tYXggPT0gIm1pbiIpIHsNCiAgICAgIG1pbihhdF9kZiAlPiUNCiAgICAgICAgICAgIGZpbHRlcihhdHQgPT0gIkJUVk9MIiB8IGF0dCA9PSAiU1RWT0wiKSAlPiUNCiAgICAgICAgICAgIC4kdHJhZGVwcmljZSAlPiUNCiAgICAgICAgICAgIGN1bW1pbigpKQ0KICAgIH0gZWxzZSBpZiAobWlubWF4ID09ICJtYXgiKSB7DQogICAgICBtYXgoYXRfZGYgJT4lDQogICAgICAgICAgICBmaWx0ZXIoYXR0ID09ICJCVFZPTCIgfCBhdHQgPT0gIlNUVk9MIikgJT4lDQogICAgICAgICAgICAuJHRyYWRlcHJpY2UgJT4lDQogICAgICAgICAgICBjdW1tYXgoKSkNCiAgICB9IGVsc2UgcXVpdCgpDQogIH0gZWxzZSB7DQogICAgICBOQQ0KICB9DQp9DQpgYGANCg0KYGBge3J9DQpvYnBfbWlubWF4X2F0dHNfZGYgPC0gb3JkZXJfYXR0c19jdW1zdW1zX2VuaGFuY2VkX2RmICU+JSANCiAgc2VsZWN0KE5PLCBTRUNDT0RFLCBEQVRFLCBPQlBMT1ROTywgQVRULA0KICAgICAgICAgREFURVRJTUVNTExTLCBQUklDRSwgVFJBREVQUklDRSkgJT4lIA0KICBncm91cF9ieShTRUNDT0RFLCBEQVRFLCBPQlBMT1ROTykgJT4lIA0KICBzdW1tYXJpc2UoT0JQQkVHSU4gPSBtaW4oREFURVRJTUVNTExTKSwgT0JQRU5EID0gbWF4KERBVEVUSU1FTUxMUyksIA0KICAgICAgICAgICAgT0JQQkVHSU5OTyA9IG1pbihOTyksIE9CUEVORE5PID0gbWF4KE5PKSwNCiAgICAgICAgICAgIE9CUE1JTlBSSUNFID0gbWluKFBSSUNFKSwgT0JQTUFYUFJJQ0UgPSBtYXgoUFJJQ0UpKQ0Kb2JwX21pbm1heF9hdHRzX2RmDQpgYGANCg0KYGBge3J9DQpvYnBfY3VtX21pbm1heF9hdHRzX2RmIDwtIGxlZnRfam9pbihvYnBfY3VtX2F0dHNfZGYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JwX21pbm1heF9hdHRzX2RmICU+JSBzZWxlY3QoU0VDQ09ERSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERBVEUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQlBMT1ROTywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9CUEJFR0lOLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0JQQkVHSU5OTywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9CUEVORE5PLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0JQRU5ELA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0JQTUlOUFJJQ0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQlBNQVhQUklDRSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IGMoIlNFQ0NPREUiLCAiREFURSIsICJPQlBMT1ROTyIpKSAlPiUgDQogIHNlbGVjdChTRUNDT0RFLCBEQVRFLCBPQlBMT1ROTywgVFJBREVWT0wsIEJVWVNFTExPQlAsDQogICAgICAgICBPQlBCRUdJTiwgT0JQRU5ELCBPQlBCRUdJTk5PLCBPQlBFTkROTywgT0JQTUlOUFJJQ0UsIE9CUE1BWFBSSUNFLA0KICAgICAgICAgVFJBREVTTk9UUkFERVMpICMsIEJVWVNFTExZSUVMRCwgT0JQVERWT0xSQVRJTywgTUlOTUFYUkFUSU8pDQpvYnBfY3VtX21pbm1heF9hdHRzX2RmDQpgYGANCg0KYGBge3J9DQoNCmBgYA0KDQpgYGB7cn0NCm9icF9jdW1fYXR0c19lbmhfZGYgPC0gaW5uZXJfam9pbihvYnBfY3VtX21pbm1heF9hdHRzX2RmLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyX2F0dHNfY3Vtc3Vtc19lbmhhbmNlZF9kZiAlPiUgc2VsZWN0KFNFQ0NPREUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgREFURSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQlBMT1ROTywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCUFJPRklULA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNQUk9GSVQpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gYygiU0VDQ09ERSIsICJEQVRFIiwgIk9CUExPVE5PIikpICU+JSANCiAgc2VsZWN0KFNFQ0NPREUsIERBVEUsIE9CUExPVE5PLCBUUkFERVZPTCwgQlVZU0VMTE9CUCwNCiAgICAgICAgIEJQUk9GSVQsIFNQUk9GSVQsDQogICAgICAgICBPQlBCRUdJTiwgT0JQRU5ELCBPQlBCRUdJTk5PLCBPQlBFTkROTywgT0JQTUlOUFJJQ0UsIE9CUE1BWFBSSUNFLA0KICAgICAgICAgVFJBREVTTk9UUkFERVMpICU+JSAjLCBCVVlTRUxMWUlFTEQsIE9CUFREVk9MUkFUSU8sIE1JTk1BWFJBVElPKSAlPiUgDQogIHJlbmFtZSgic2VjY29kZSIgPSAiU0VDQ09ERSIsDQogICAgICAgICAiZGRhdGUiID0gIkRBVEUiLA0KICAgICAgICAgIm9icGxvdG5vIiA9ICJPQlBMT1ROTyIsDQogICAgICAgICAidHJhZGV2b2wiID0gIlRSQURFVk9MIiwNCiAgICAgICAgICJidXlzZWxsb2JwIiA9ICJCVVlTRUxMT0JQIiwNCiAgICAgICAgICJicHJvZml0IiA9ICJCUFJPRklUIiwNCiAgICAgICAgICJzcHJvZml0IiA9ICJTUFJPRklUIiwNCiAgICAgICAgICJvYnBiZWdpbiIgPSAiT0JQQkVHSU4iLA0KICAgICAgICAgIm9icGVuZCIgPSAiT0JQRU5EIiwNCiAgICAgICAgICJvYnBiZWdpbm5vIiA9ICJPQlBCRUdJTk5PIiwNCiAgICAgICAgICJvYnBlbmRubyIgPSAiT0JQRU5ETk8iLA0KICAgICAgICAgIm9icG1pbnByaWNlIiA9ICJPQlBNSU5QUklDRSIsDQogICAgICAgICAib2JwbWF4cHJpY2UiID0gIk9CUE1BWFBSSUNFIiwNCiAgICAgICAgICJicHJvZml0IiA9ICJCUFJPRklUIiwNCiAgICAgICAgICJzcHJvZml0IiA9ICJTUFJPRklUIiwNCiAgICAgICAgICJ0cmFkZXNub3RyYWRlcyIgPSAiVFJBREVTTk9UUkFERVMiKSAlPiUgDQogIGRpc3RpbmN0KCkNCiAgICAgICAgICMgImJ1eXNlbGx5aWVsZCIgPSAiQlVZU0VMTFlJRUxEIiwNCiAgICAgICAgICMgIm9icHRkdm9scmF0aW8iID0gIk9CUFREVk9MUkFUSU8iLA0KICAgICAgICAgIyAibWlubWF4cmF0aW8iID0gIk1JTk1BWFJBVElPIikNCm9icF9jdW1fYXR0c19lbmhfZGYNCmBgYA0KDQpgYGB7cn0NCnRkX3ZvbF9zdW1fZGYgPC0gb2JwX2N1bV9hdHRzX2VuaF9kZiAlPiUgDQogIGdyb3VwX2J5KHNlY2NvZGUsIGRkYXRlKSAlPiUgDQogIHN1bW1hcmlzZSh0ZHZvbHN1bSA9IHN1bSh0cmFkZXZvbCkpDQoNCm9icF9jdW1fYXR0c19lbmhfdm9sYXJyYW5nZWRfZGYgPC0gbGVmdF9qb2luKG9icF9jdW1fYXR0c19lbmhfZGYsDQogICAgICAgICAgdGRfdm9sX3N1bV9kZiwNCiAgICAgICAgICBieSA9IGMoInNlY2NvZGUiLCAiZGRhdGUiKSkgJT4lIA0KICBtdXRhdGUob2Jwc2hhcmVpbnRkID0gdHJhZGV2b2wgLyB0ZHZvbHN1bSkgJT4lIA0KICBzZWxlY3QoLXRkdm9sc3VtKSAlPiUgDQogIGFycmFuZ2Uoc2VjY29kZSwgZGRhdGUsIGRlc2Mob2Jwc2hhcmVpbnRkKSkNCg0Kb2JwX2N1bV9hdHRzX2VuaF92b2xhcnJhbmdlZF9kZg0KYGBgDQoNCmBgYHtyfQ0Kb3B0aW9ucyhkaWdpdHMuc2VjcyA9IDMpDQpvYnBfY3VtX2F0dHNfZW5oX3ZvbGFycmFuZ2VkX2RmICU+JQ0KICB3cml0ZV9jc3YoIi4uL29yZGVyLWJvb2stcGxvdC1maW5kL2N1bV9lcnJvcnMvcmVzb3VyY2VzL2Zvcl93ZWJfYXBwL29icF9jdW1fYXR0c19lbmhfZGYuY3N2IiwNCiAgICAgICAgICAgIG5hID0gIiIpDQpgYGANCg0KYGBge3J9DQpvcmRlcl9hdHRzX2N1bXN1bXNfZW5oMl9kZiA8LSBvcmRlcl9hdHRzX2N1bXN1bXNfZW5oYW5jZWRfZGYgJT4lIA0KICBtdXRhdGUocGNvbG9yID0gaWZfZWxzZShBVFQgPT0gIkJPVk9MIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICJhcXVhbWFyaW5lIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGlmX2Vsc2UoQVRUID09ICJTT1ZPTCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvcmFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIzAwNDQ4MSIpKSwNCiAgICAgICAgIHBzaGFwZSA9IDRMLA0KICAgICAgICAgcHNpemUgPSAwLjUpDQpvcmRlcl9hdHRzX2N1bXN1bXNfZW5oMl9kZg0KYGBgDQoNCmBgYHtyfQ0Kb3JkZXJfYXR0c19jdW1zdW1zX2VuaDRfZGYgPC0gb3JkZXJfYXR0c19jdW1zdW1zX2VuaDJfZGYgJT4lIA0KICBhcnJhbmdlKFNFQ0NPREUsIERBVEUsIE5PKSAlPiUgDQogIHJlbmFtZSgibm5vIiA9ICJOTyIsDQogICAgICAgICAic2VjY29kZSIgPSAiU0VDQ09ERSIsDQogICAgICAgICAiZGF0ZXRpbWVtbGxzIiA9ICJEQVRFVElNRU1MTFMiLA0KICAgICAgICAgInByaWNlIiA9ICJQUklDRSIsDQogICAgICAgICAidHJhZGVwcmljZSIgPSAiVFJBREVQUklDRSIsDQogICAgICAgICAidm9sdW1lIiA9ICJWT0xVTUUiLA0KICAgICAgICAgImRkYXRlIiA9ICJEQVRFIiwNCiAgICAgICAgICJ0dGltZV9zIiA9ICJUSU1FX1MiLA0KICAgICAgICAgIm9icGxvdG5vIiA9ICJPQlBMT1ROTyIsDQogICAgICAgICAiYXR0IiA9ICJBVFQiLA0KICAgICAgICAgInZhbCIgPSAiVkFMIiwNCiAgICAgICAgICJzaGFyZWJhbCIgPSAiU0hBUkVCQUwiKSAlPiUgDQogIHNlbGVjdCgtQlBST0ZJVCwgLVNQUk9GSVQsIC1PQlBNSU5UUFJJQ0UsIC1PQlBNQVhUUFJJQ0UpDQojIG9wdGlvbnMoZGlnaXRzLnNlY3MgPSAzKQ0Kb3JkZXJfYXR0c19jdW1zdW1zX2VuaDRfZGYgJT4lDQogIHdyaXRlX2NzdigiLi4vb3JkZXItYm9vay1wbG90LWZpbmQvY3VtX2Vycm9ycy9yZXNvdXJjZXMvZm9yX3dlYl9hcHAvb3JkZXJfYXR0c19jdW1zdW1zX2VuaDRfZGYuY3N2IiwNCiAgICAgICAgICAgIG5hID0gIiIpDQpvcmRlcl9hdHRzX2N1bXN1bXNfZW5oNF9kZg0KYGBgDQoNCmBgYHtyfQ0Kb3JkZXJfYXR0c19jdW1zdW1zX2VuaDRfZGYgJT4lIA0KICBmaWx0ZXIob2JwbG90bm8gPT0gNDg4NTEsIGF0dCA9PSAiU1RWT0wiKSAlPiUgDQogIHNlbGVjdChubm8sIHByaWNlLCBhdHQsIHRyYWRlcHJpY2UsIHNvYnAsIGJvYnApDQpgYGANCg0K